package com.easipass;

// FileComparator.java
import com.easipass.model.DiffLine;
import com.easipass.model.DiffType;
import java.util.*;
import java.util.stream.Collectors;

public class FileComparator {

    public List<DiffLine> compareFiles(List<String> leftLines, List<String> rightLines) {
        List<DiffLine> result = new ArrayList<>();

        // 使用动态规划计算最长公共子序列
        int[][] dp = computeLCS(leftLines, rightLines);

        int i = leftLines.size();
        int j = rightLines.size();

        // 回溯构建差异结果
        while (i > 0 || j > 0) {
            if (i > 0 && j > 0 && leftLines.get(i-1).equals(rightLines.get(j-1))) {
                // 相同行
                result.add(0, new DiffLine(i, j, leftLines.get(i-1), rightLines.get(j-1), DiffType.SAME));
                i--;
                j--;
            } else if (j > 0 && (i == 0 || dp[i][j-1] >= dp[i-1][j])) {
                // 仅右边存在
                result.add(0, new DiffLine(-1, j, "", rightLines.get(j-1), DiffType.RIGHT_ONLY));
                j--;
            } else if (i > 0 && (j == 0 || dp[i][j-1] < dp[i-1][j])) {
                // 仅左边存在
                result.add(0, new DiffLine(i, -1, leftLines.get(i-1), "", DiffType.LEFT_ONLY));
                i--;
            }
        }

        return result;
    }

    private int[][] computeLCS(List<String> left, List<String> right) {
        int m = left.size();
        int n = right.size();
        int[][] dp = new int[m+1][n+1];

        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (left.get(i-1).equals(right.get(j-1))) {
                    dp[i][j] = dp[i-1][j-1] + 1;
                } else {
                    dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
                }
            }
        }
        return dp;
    }

    /**
     * 应用单行覆盖操作
     */
    public List<DiffLine> applyLineOverride(List<DiffLine> currentDiff, int lineIndex, boolean useLeft) {
        List<DiffLine> newDiff = new ArrayList<>(currentDiff);
        DiffLine targetLine = newDiff.get(lineIndex);

        if (useLeft) {
            // 用左边覆盖右边
            newDiff.set(lineIndex, new DiffLine(
                    targetLine.getLeftLineNumber(),
                    targetLine.getRightLineNumber(),
                    targetLine.getLeftContent(),
                    targetLine.getLeftContent(),  // 右边内容变为左边内容
                    DiffType.SAME
            ));
        } else {
            // 用右边覆盖左边
            newDiff.set(lineIndex, new DiffLine(
                    targetLine.getLeftLineNumber(),
                    targetLine.getRightLineNumber(),
                    targetLine.getRightContent(), // 左边内容变为右边内容
                    targetLine.getRightContent(),
                    DiffType.SAME
            ));
        }

        return newDiff;
    }

    /**
     * 完全用右边覆盖左边
     */
    public List<String> fullOverrideRightToLeft(List<DiffLine> diff) {
        return diff.stream()
                .map(line -> {
                    // 总是使用右边内容，如果右边不存在则使用左边
                    return line.getRightContent().isEmpty() ?
                            line.getLeftContent() : line.getRightContent();
                })
                .filter(content -> !content.isEmpty())
                .collect(Collectors.toList());
    }
}